<script setup lang="tsx">
import { ContentWrap } from '@/components/ContentWrap'
import { useI18n } from '@/hooks/web/useI18n'
import { Table } from '@/components/Table'
import { ref, unref, nextTick, watch, reactive } from 'vue'
import {
  ElTree,
  ElInput,
  ElDivider,
  ElTag,
  ElUpload,
  ElIcon,
  ElMessage,
  TableColumnCtx
} from 'element-plus'

import {
  getUserListApi,
  getTreeDepartmentsApi,
  // getUserByIdApi,
  addUserApi,
  UpdateUserApi,
  deleteUserByIdApi,
  downloadUserTemplateApi
} from '@/api/department'
import type { DepartmentItem, DepartmentUserItem, Role } from '@/api/department/types'
import { useTable } from '@/hooks/web/useTable'
import { Search } from '@/components/Search'
import Write from './components/UserWrite.vue'
import Detail from './components/UserDetail.vue'
import { Dialog } from '@/components/Dialog'
import { getRoleListApi } from '@/api/role'
import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas'
import { BaseButton } from '@/components/Button'
import * as XLSX from 'xlsx'
import { Plus } from '@element-plus/icons-vue'
import { useButtonPermiss, UploadUrlParams } from '@/utils/buttonpermiss'
const haspermiss = ref<String[]>([])
const getUseButtonPermiss = () => {
  useButtonPermiss().then((res) => {
    haspermiss.value = res
  })
}
getUseButtonPermiss()
// const PATH_URL = import.meta.env.VITE_API_BASE_PATH
import { useUserStoreWithOut } from '@/store/modules/user'
const userStore = useUserStoreWithOut()
// const uploadUrl = PATH_URL + 'api/User/ExportUsers'
const headers = ref({ Authorization: userStore.getToken ?? '' })
// console.log('uploadUrl', uploadUrl)
// const { uploadUrl, headers } = UploadUrlParams
// const PATH_URL =
// process.env.NODE_ENV == 'development'
// ? import.meta.env.VITE_API_BASE_PATH
// : window.webkitURL.webApiBaseUrl

// process.env.NODE_ENV == 'development'
// ? import.meta.env.VITE_API_BASE_PATH
// : window.webkitURL.webApiBaseUrl
// PATH_URL + 'api/User/ExportUsers'

const { t } = useI18n()
interface user {
  depNo: string
  depName: string
  userNo: string
  userName: string
  loginName: string
  userSex: string
  roleName: string
  isEnabled: number
  createTime: string
  userAge: number
  userJob: string
}
interface userExport {
  部门编号: string
  部门名称: string
  用户编号: string
  用户名: string
  登录账号: string
  性别: string
  角色: string
  年龄: number
  职业: string
  初始密码: string
  状态: string
  创建时间: string
}

let list: user[] = []
const { tableRegister, tableState, tableMethods } = useTable({
  fetchDataApi: async () => {
    const { pageSize, currentPage } = tableState
    const res = await getUserListApi({
      pageNo: unref(currentPage),
      pageRow: unref(pageSize),
      pageModel: { ...unref(searchParams) }
    })
    list = res.data.pageModels || []
    return {
      list: list,
      total: res.data.totalCount || 0
    }
  },
  fetchDelApi: async () => {
    const res = await deleteUserByIdApi(unref(ids))
    return !!res
  }
})
const { total, loading, dataList, pageSize, currentPage } = tableState
const { getList, getElTableExpose, delList } = tableMethods

const crudSchemas = reactive<CrudSchema[]>([
  {
    field: 'selection',
    search: {
      hidden: true
    },
    form: {
      hidden: true
    },
    detail: {
      hidden: true
    },
    table: {
      type: 'selection'
    }
  },
  {
    field: 'index',
    label: t('userDemo.index'),
    form: {
      hidden: true
    },
    search: {
      hidden: true
    },
    detail: {
      hidden: true
    },
    table: {
      type: 'index'
    }
  },
  {
    field: 'depNo',
    label: t('userDemo.depNo'),
    form: {
      hidden: true
    },
    search: {
      hidden: true
    },
    table: {
      hidden: true
    }
  },
  {
    field: 'depGuid',
    label: t('userDemo.department'),
    slots: {
      default: (data) => {
        return <>{data.row.depName}</>
      }
    },
    search: {
      hidden: false,
      component: 'TreeSelect',
      componentProps: {
        nodeKey: 'guid',
        props: {
          label: 'departmentName',
          value: 'guid',
          children: 'children'
        },
        placeholder: '请选择部门',
        highlightCurrent: true,
        expandOnClickNode: false,
        checkStrictly: true,
        checkOnClickNode: true,
        clearable: true,
        filterable: true
      },
      optionApi: async () => {
        // const res = await getTreeDepartmentsApi({}) //  getDepartmentApi()
        // if (res.data) {
        //   return res.data //.list
        // } else {
        return departmentList.value || []
        // }
      }
    },
    form: {
      component: 'TreeSelect',
      componentProps: {
        nodeKey: 'guid',
        props: {
          label: 'departmentName',
          value: 'guid',
          children: 'children'
        },
        placeholder: '请选择部门',
        highlightCurrent: true,
        expandOnClickNode: false,
        checkStrictly: true,
        checkOnClickNode: true,
        clearable: true,
        filterable: true
      },
      optionApi: async () => {
        return departmentList.value || []
        // const res = await getTreeDepartmentsApi({}) //  getDepartmentApi()
        // if (res.data) {
        //   return res.data //.list
        // } else {
        //   return []
        // }
      }
    },
    table: {
      hidden: false
    },
    detail: {
      slots: {
        default: (data) => {
          return <>{data.depName || '-'}</>
        }
      }
    }
  },
  {
    field: 'userNo',
    label: t('userDemo.userNo')
  },
  {
    field: 'userName',
    label: t('userDemo.username')
  },
  {
    field: 'loginName',
    label: t('userDemo.loginName')
  },
  {
    field: 'userSex',
    label: t('userDemo.userSex'),
    search: { hidden: true },
    form: {
      component: 'Select',
      componentProps: {
        clearable: true,
        placeholder: '请选择性别'
      },
      optionApi: () => {
        return [
          { label: '男', value: '男' },
          { label: '女', value: '女' }
        ]
      }
    }
  },
  {
    field: 'roleGuid',
    label: t('userDemo.role'),
    slots: {
      default: (data) => {
        return <>{data.row.roleName}</>
      }
    },
    search: {
      hidden: false,
      component: 'Select',
      value: [],
      componentProps: {
        placeholder: '请选择角色'
      },
      optionApi: async () => {
        const res = roleList.value || [] //await getRoleListApi({})
        return res?.map((v) => ({
          label: v.name,
          value: v.guid
        }))
      }
    },
    form: {
      component: 'Select',
      componentProps: {
        placeholder: '请选择角色'
      },
      optionApi: async () => {
        const res = roleList.value || []
        return res?.map((v) => ({
          label: v.name,
          value: v.guid
        }))
      }
    },
    detail: {
      slots: {
        default: (data) => {
          return <>{data.roleName}</>
        }
      }
    }
  },
  {
    field: 'userAge',
    label: '年龄',
    form: {
      component: 'Input',
      componentProps: {
        placeholder: '请输入年龄',
        type: 'number'
      }
    },
    search: {
      hidden: true
    },
    table: {
      hidden: true
    }
  },
  {
    field: 'userJob',
    label: '职业',
    form: {
      component: 'Input'
    },
    search: {
      hidden: true
    },
    table: {
      hidden: true
    }
  },
  {
    field: 'remark',
    label: t('common.remark'),
    form: {
      component: 'Input'
    },
    search: {
      hidden: true
    },
    table: {
      hidden: true
    }
  },
  {
    field: 'createTime',
    label: t('userDemo.createTime'),
    width: 200,
    form: {
      hidden: true
    },
    search: {
      hidden: true
    }
  },
  {
    field: 'createUserName',
    label: '创建人',
    form: {
      hidden: true
    },
    search: {
      hidden: true
    },
    table: {
      hidden: true
    }
  },
  {
    field: 'modifyTime',
    label: '修改时间',
    form: {
      hidden: true
    },
    search: {
      hidden: true
    },
    table: {
      hidden: true
    }
  },
  {
    field: 'modifyUserName',
    label: '修改人',
    form: {
      hidden: true
    },
    search: {
      hidden: true
    },
    table: {
      hidden: true
    }
  },

  {
    field: 'isEnabled',
    label: t('menu.status'),
    slots: {
      default: (data: any) => {
        return (
          <>
            <ElTag type={data.row.isEnabled === 0 ? 'danger' : 'success'}>
              {data.row.isEnabled === 1 ? t('userDemo.enable') : t('userDemo.disable')}
            </ElTag>
          </>
        )
      }
    },
    form: {
      component: 'Select',
      value: 1,
      componentProps: {
        placeholder: '请选择状态'
      },
      optionApi: async () => {
        return [
          { label: t('userDemo.enable'), value: 1 },
          { label: t('userDemo.disable'), value: 0 }
        ]
      }
    },
    detail: {
      slots: {
        default: (data) => {
          return <>{data.isEnabled === 1 ? t('userDemo.enable') : t('userDemo.disable')}</>
        }
      }
    },
    search: {
      component: 'Select',
      value: [],
      componentProps: {
        placeholder: '请选择'
      },
      optionApi: async () => {
        return [
          { label: t('userDemo.enable'), value: 1 },
          { label: t('userDemo.disable'), value: 0 }
        ]
      }
    }
  },
  {
    field: 'action',
    label: t('userDemo.action'),
    width: 100,
    align: 'center',
    fixed: 'right',
    form: {
      hidden: true
    },
    detail: {
      hidden: true
    },
    search: {
      hidden: true
    },
    table: {
      width: 240,
      slots: {
        default: (data: any) => {
          const row = data.row as DepartmentUserItem
          return (
            <>
              {haspermiss.value.includes('编辑') ? (
                <BaseButton type="primary" onClick={() => action(data.row, 'edit')}>
                  {t('exampleDemo.edit')}
                </BaseButton>
              ) : null}
              <BaseButton type="success" onClick={() => action(row, 'detail')}>
                {t('exampleDemo.detail')}
              </BaseButton>
              {haspermiss.value.includes('删除') ? (
                <BaseButton type="danger" onClick={() => delData(data.row)}>
                  {t('exampleDemo.del')}
                </BaseButton>
              ) : null}
            </>
          )
        }
      }
    }
  }
])

const { allSchemas } = useCrudSchemas(crudSchemas)

const searchParams = ref({
  depGuid: userStore.userInfo.depGuid ? userStore.userInfo.depGuid : undefined
})
const setSearchParams = (params: any) => {
  currentPage.value = 1
  searchParams.value = params
  getList()
}

const treeEl = ref<typeof ElTree>()

const currentNodeKey = ref('')
const departmentList = ref<DepartmentItem[]>([])
const roleList = ref<Role[]>([])
const fetchDepartment = async () => {
  const res = await getTreeDepartmentsApi({})
  let depArr: DepartmentItem[] = []
  res.data.map((item) => {
    depArr.push({
      ...item,
      departmentName: item.depNo + '~' + item.depName,
      children: HandleItem(item)
    })
  })
  function HandleItem(item) {
    let arr: DepartmentItem[] = []
    item.children?.map((child) => {
      child = {
        ...child,
        departmentName: child.depNo + '~' + child.depName,
        children: HandleItem(child)
      }
      arr.push(child)
    })
    return arr
  }
  console.log('-------------', res.data, depArr)
  departmentList.value = depArr
  const roleRes = await getRoleListApi({ pageFlag: false })
  let arr: Role[] = []
  roleRes.data.pageModels?.map((item) => {
    if (item.isEnabled == 1) {
      arr.push(item)
    }
  })

  roleList.value = arr
}
fetchDepartment()

const currentDepartment = ref('')
watch(
  () => currentDepartment.value,
  (val) => {
    unref(treeEl)!.filter(val)
  }
)

const currentChange = (data: DepartmentItem) => {
  // if (data.children) return
  // currentNodeKey.value = data.id
  currentPage.value = 1
  getList()
}

const filterNode = (value: string, data: DepartmentItem) => {
  if (!value) return true
  return data.depName.includes(value)
}

const dialogVisible = ref(false)
const dialogTitle = ref('')

const currentRow = ref<DepartmentUserItem>()
const actionType = ref('')

const AddAction = () => {
  dialogTitle.value = t('exampleDemo.add')
  currentRow.value = undefined
  dialogVisible.value = true
  actionType.value = ''
}

const delLoading = ref(false)
const ids = ref<string[]>([])

const delData = async (row?: DepartmentUserItem) => {
  const elTableExpose = await getElTableExpose()
  ids.value = row
    ? [row.guid]
    : elTableExpose?.getSelectionRows().map((v: DepartmentUserItem) => v.guid) || []
  delLoading.value = true

  await delList(unref(ids).length).finally(() => {
    delLoading.value = false
  })
}

const action = (row: DepartmentUserItem, type: string) => {
  dialogTitle.value = t(type === 'edit' ? 'exampleDemo.edit' : 'exampleDemo.detail')
  actionType.value = type
  currentRow.value = { ...row, department: unref(treeEl)?.getCurrentNode() || {} }
  dialogVisible.value = true
}

const writeRef = ref<ComponentRef<typeof Write>>()

const saveLoading = ref(false)

const save = async () => {
  const write = unref(writeRef)
  const formData = await write?.submit()
  if (formData) {
    saveLoading.value = true
    try {
      let p = {
        depNo: '',
        depName: '',
        roleName: ''
      }
      departmentList.value.map((item) => {
        if (item.guid == formData.depGuid) {
          p.depNo = item.depNo
          p.depName = item.depName
        } else {
          findItem(item, formData)
        }
      })
      function findItem(item, formData) {
        item?.children?.map((nitem) => {
          if (nitem.guid == formData.depGuid) {
            p.depNo = nitem.depNo
            p.depName = nitem.depName
          } else {
            if (item?.children) findItem(nitem, formData)
          }
        })
      }
      roleList.value.map((item) => {
        if (item.guid == formData.roleGuid) {
          p.roleName = item?.name || ''
        }
      })

      console.log('formData---', { formData, p })

      let res
      if (actionType.value == 'edit') {
        res = await UpdateUserApi({ ...formData, ...p }).finally(() => {
          saveLoading.value = false
        })
      } else {
        formData.guid = ''
        res = await addUserApi({ ...formData, ...p }).finally(() => {
          saveLoading.value = false
        })
      }
      if (res) {
        currentPage.value = 1
        getList()
      }
    } catch (error) {
      console.log(error)
    } finally {
      saveLoading.value = false
      dialogVisible.value = false
    }
  }
}
const showExport = ref(false)

const handleData = () => {
  let arr: userExport[] = []
  list.map((item) => {
    arr.push({
      部门编号: item.depNo,
      部门名称: item.depName,
      用户编号: item.userNo,
      用户名: item.userName,
      登录账号: item.loginName,
      初始密码: '',
      性别: item.userSex,
      年龄: item.userAge,
      职业: item.userJob,
      角色: item.roleName,
      状态: item.isEnabled == 1 ? '启用' : '禁用',
      创建时间: item.createTime
    })
  })
  return arr
}
const exportToExcel = () => {
  // 创建一个工作簿
  const workbook = XLSX.utils.book_new()
  // 创建一个工作表
  const worksheet = XLSX.utils.json_to_sheet(handleData())

  // 将工作表添加到工作簿
  XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1')

  // 生成Excel文件
  XLSX.writeFile(workbook, '用户列表.xlsx')
}
const successFile = (e) => {
  console.log('successFile-------', e)
  if (e.code == 0) {
    ElMessage.success('导入成功')
    showExport.value = false
    getList()
  } else {
    ElMessage.error(e.msg || '导入失败')
  }
}
const downExcel = async () => {
  const res = await downloadUserTemplateApi()
  if (res) {
    const excelFile = new Blob([res.data], {
      type: 'application/vnd.ms-excel'
    })

    // const url = URL.createObjectURL(excelFile)
    const url = window.URL.createObjectURL(excelFile)
    const a: HTMLAnchorElement = document.createElement('a')
    // 设置<a>元素的属性
    a.href = url
    a.download = '用户模板.xlsx'
    // 将<a>元素添加到文档中
    document.body.appendChild(a)
    // 触发点击事件
    a.click()
    URL.revokeObjectURL(a.href)
    // 移除<a>元素
    document.body.removeChild(a)
  }
}
</script>

<template>
  <div class="flex w-100% h-100%">
    <!-- <ContentWrap class="w-250px">
      <div class="flex justify-center items-center">
        <div class="flex-1">{{ t('userDemo.departmentList') }}</div>
        <ElInput
          v-model="currentDepartment"
          class="flex-[2]"
          :placeholder="t('userDemo.searchDepartment')"
          clearable
        />
      </div>
      <ElDivider />
      <ElTree
        ref="treeEl"
        :data="departmentList"
        default-expand-all
        :expand-on-click-node="false"
        node-key="guid"
        :current-node-key="currentNodeKey"
        :props="{
          label: 'depName',
          children: 'children'
        }"
        :filter-node-method="filterNode"
        @current-change="currentChange"
      >
        <template #default="{ data }">
          <div :title="data.depName" class="whitespace-nowrap overflow-ellipsis overflow-hidden">
            {{ data.depName }}
          </div>
        </template>
      </ElTree>
    </ContentWrap> -->
    <!-- class="flex-[3] ml-20px" -->
    <ContentWrap>
      <Search
        :schema="allSchemas.searchSchema"
        @reset="setSearchParams"
        @search="setSearchParams"
      />

      <div class="mb-10px">
        <BaseButton type="primary" @click="AddAction" v-if="haspermiss.includes('新增')">{{
          t('exampleDemo.add')
        }}</BaseButton>
        <BaseButton
          :loading="delLoading"
          type="danger"
          @click="delData()"
          v-if="haspermiss.includes('删除')"
        >
          {{ t('exampleDemo.del') }}
        </BaseButton>
        <BaseButton type="primary" @click="showExport = true" v-if="haspermiss.includes('导入')">{{
          t('exampleDemo.import')
        }}</BaseButton>
        <BaseButton type="primary" @click="exportToExcel" v-if="haspermiss.includes('导出')">{{
          t('exampleDemo.exprot')
        }}</BaseButton>
        <BaseButton type="primary" @click="downExcel">下载模板</BaseButton>
      </div>
      <Table
        v-model:current-page="currentPage"
        v-model:page-size="pageSize"
        :reserveIndex="true"
        :columns="allSchemas.tableColumns"
        :data="dataList"
        :loading="loading"
        @register="tableRegister"
        :showAction="true"
        :pagination="{
          total
        }"
      />
    </ContentWrap>

    <Dialog v-model="dialogVisible" :title="dialogTitle">
      <Write
        v-if="actionType !== 'detail'"
        ref="writeRef"
        :form-schema="allSchemas.formSchema"
        :current-row="currentRow"
      />

      <Detail
        v-if="actionType === 'detail'"
        :detail-schema="allSchemas.detailSchema"
        :current-row="currentRow"
      />

      <template #footer>
        <BaseButton
          v-if="actionType !== 'detail'"
          type="primary"
          :loading="saveLoading"
          @click="save"
        >
          {{ t('exampleDemo.save') }}
        </BaseButton>
        <BaseButton @click="dialogVisible = false">{{ t('dialogDemo.close') }}</BaseButton>
      </template>
    </Dialog>
    <Dialog v-model="showExport" title="导入模板">
      <div class="uploaddiv">
        <!-- :action="uploadUrl1 + 'api/User/ExportUsers'" -->
        <ElUpload
          accept=".xlsx, .xls"
          drag
          action="api/User/ExportUsers"
          :headers="headers"
          :on-success="successFile"
        >
          <el-icon class="el-icon--upload"><Plus /></el-icon>
          <div class="el-upload__text">点击或拖拽文件到此处上传</div>
          <div class="el-upload__text">支持.xlsx, .xls</div>
        </ElUpload>
      </div>
      <template #footer>
        <BaseButton @click="showExport = false">{{ t('dialogDemo.close') }}</BaseButton>
      </template>
    </Dialog>
  </div>
</template>
